package online.longzipeng.mywebdemo.config;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author: lzp
 * @Description: 简单模式配置
 * @Date: 2024/1/10 10:28
 */
@Configuration
public class RabbitMqConfig {

	public static final String QUEUE_NAME = "my_queue"; //队列名称

	/**
	 * Queue（队列）
	 */
	@Bean
	public Queue simpleQueue() {
		/**
		 * name：队列名称。
		 * durable：是否持久化,默认是false,持久化队列（内部会有一个actualName: 队列的真实名称，默认用name参数，如果name为空，则根据规则生成一个）
		 * exclusive：默认也是false，只能被当前创建的连接使用，而且当连接关闭后队列即被删除。此参考优先级高于durable
		 * autoDelete：是否自动删除，当没有生产者或者消费者使用此队列，该队列会自动删除。
		 * arguments：设置队列的属性参数
		 *  1、x-message-ttl：消息的过期时间，单位：毫秒；
		 *  2、x-expires：队列过期时间，队列在多长时间未被访问将被删除，单位：毫秒；
		 *  3、x-max-length：队列最大长度，超过该最大值，则将从队列头部开始删除消息；
		 *  4、x-max-length-bytes：队列消息内容占用最大空间，受限于内存大小，超过该阈值则从队列头部开始删除消息；
		 *  5、x-overflow：设置队列溢出行为。这决定了当达到队列的最大长度时消息会发生什么。有效值是drop-head、reject-publish或reject-publish-dlx。仲裁队列类型仅支持drop-head；
		 *  6、x-dead-letter-exchange：死信交换器名称，过期或被删除（因队列长度超长或因空间超出阈值）的消息可指定发送到该交换器中；
		 *  7、x-dead-letter-routing-key：死信消息路由键，在消息发送到死信交换器时会使用该路由键，如果不设置，则使用消息的原来的路由键值
		 *  8、x-single-active-consumer：表示队列是否是单一活动消费者，true时，注册的消费组内只有一个消费者消费消息，其他被忽略，false时消息循环分发给所有消费者(默认false)
		 *  9、x-max-priority：队列要支持的最大优先级数;如果未设置，队列将不支持消息优先级；
		 * 10、x-queue-mode（Lazy mode）：将队列设置为延迟模式，在磁盘上保留尽可能多的消息，以减少RAM的使用;如果未设置，队列将保留内存缓存以尽可能快地传递消息；
		 * 11、x-queue-master-locator：在集群模式下设置镜像队列的主节点信息。
		 */
		return new Queue(QUEUE_NAME, true, false, false, null);
	}

//	消息回调开启
//  ConfirmCallback： 当消息到达交换机触发回调
//  ReturnsCallback：消息(带有路由键routingKey)到达交换机，与交换机的所有绑定键进行匹配，触发回调
//	publisher-confirm-type: correlated
//	publisher-returns: true
	@Bean
	public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory) {
		RabbitTemplate rabbitTemplate = new RabbitTemplate();
		rabbitTemplate.setConnectionFactory(connectionFactory);
		//设置开启Mandatory,才能触发回调函数,无论消息推送结果怎么样都强制调用回调函数
		rabbitTemplate.setMandatory(true);
		//确认消息发送到交换机
		rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
			System.out.println("=======================> ConfirmCallback <=======================");
			System.out.println("ConfirmCallback ===>"+"相关数据："+correlationData);
			System.out.println("ConfirmCallback ===>"+"确认情况："+ack);
			System.out.println("ConfirmCallback ===>"+"原因："+cause);
		});

		//确认消息已发送到队列
		rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
			System.out.println("=======================> ReturnsCallback <=======================");
			System.out.println("ReturnCallback ===>"+"消息："+ message);
			System.out.println("ReturnCallback ===>"+"回应码："+replyCode);
			System.out.println("ReturnCallback ===>"+"回应信息："+replyText);
			System.out.println("ReturnCallback ===>"+"交换机："+exchange);
			System.out.println("ReturnCallback ===>"+"路由键："+routingKey);
		});
		return rabbitTemplate;
	}



}
